package experiment3.task1;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * @author 冯永龙
 * @date 2021/3/23 19:59
 */
public class PersonManager<T> {
    private List<T> list;
    public static Class<?> CLASS_TYPE = null;
    Scanner sc = new Scanner(System.in);

    public PersonManager() {
        list = new ArrayList<>();
    }

    public Class<?> createObject() {
        Scanner sc = new Scanner(System.in);
        System.out.println("请选择你管理的对象，1：学生；2：老师");
        int obj = sc.nextInt();
        Person object = null;
        //将list类型转换为用户选择的类型，并创建对象赋值
        if (obj == 1) {
            List<Student> arrayList = new ArrayList<>();
            list = (List<T>) arrayList;
            object = new Student();
            CLASS_TYPE = Student.class;
        } else if (obj == 2) {
            List<Teacher> arrayList = new ArrayList<>();
            list = (List<T>) arrayList;
            object = new Teacher();
            CLASS_TYPE = Teacher.class;
        } else {
            System.out.println("你的输入有误！");
        }

        if (object != null) createObject(object);

        return CLASS_TYPE;
    }

    /**
     * 给对象属性赋值
     *
     * @param fields 属性值
     * @param clazz  属性对应的类
     * @param o      需要赋值的对象
     */
    public void iniFields(Field[] fields, Class<?> clazz, Object o) {

        for (Field field : fields) {
            String name = field.getName();
            System.out.print(name + ": ");
            String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
            Class<?> fieldType = field.getType();
            Object var = null;
            String value = sc.nextLine();
            switch (fieldType.getName()) {
                case "java.lang.Integer":
                    var = Integer.parseInt(value);
                    break;
                case "java.lang.String":
                    var = value;
                    break;
            }
            try {
                Method method = clazz.getMethod(methodName, fieldType);
                method.invoke(o, var);
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }

    //初始化对象,并添加到list中
    public void createObject(Person person) {
        //根据用户的选择，给出需要处理的类
        Class<?> clazz = null;
        if (person instanceof Student) {
            clazz = Student.class;
        } else if (person instanceof Teacher) {
            clazz = Teacher.class;
        }


        //因为涉及到父类和子类的属性，所以需要对其分别赋值
        try {
            Object o = clazz.newInstance();
            //给父类的属性赋值
            Field[] superFields = clazz.getSuperclass().getDeclaredFields();
            iniFields(superFields, clazz, o);
            //给子类的属性赋值
            Field[] fields = clazz.getDeclaredFields();
            iniFields(fields, clazz, o);
            list.add((T) o);
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }


    }


    //添加
    public void add() {
        try {
            Person o = (Person) CLASS_TYPE.newInstance();
            createObject(o);
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

    }

    //删除对象
    public void remove(T t) {
        if (t == null || list == null) return;
        list.remove(t);
    }

    //通过id寻找
    public T findById(int id) {
        for (T t : list) {
            if (((Person) t).getId() == id) {
                System.out.println(t);
                return t;
            }
        }
        return null;
    }

    /**
     * 更新对象
     *
     * @param t 传入被更新的对象
     * @return 更新后的对象
     */
    public T update(T t) {
        //通过id找到被更新对象
        Integer id = ((Person) t).getId();
        T obj = findById(id);
        //分别给各个属性重新赋值
        Class<?> objClass = obj.getClass();
        Field[] supFields = objClass.getSuperclass().getDeclaredFields();
        iniFields(supFields, objClass, obj);
        Field[] fields = objClass.getDeclaredFields();
        iniFields(fields, objClass, obj);

        return obj;
    }


    //返回list
    public void findAll() {
        for (T t : list) {
            System.out.println(t);
        }
    }
}


